package com.xhwl.centiotdata.handler.device.impl;

import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.handler.device.DeviceIntegrationFactory;
import com.xhwl.centiotdata.handler.device.DeviceIntegrationHandler;
import com.xhwl.centiotdata.mq.producer.GeneralProducer;
import com.xhwl.centiotdata.pojo.dto.device.DeviceIntegrationConfigDTO;
import com.xhwl.centiotdata.pojo.dto.haikang.DoorHaiKangDTO;
import com.xhwl.centiotdata.service.cent.IDeviceCentService;
import com.xhwl.centiotdata.suppliersystem.haikang.DeviceHaiKangHandler;
import com.xhwl.common.constant.cent.alarm.AlarmConstant;
import com.xhwl.common.dto.cent.device.DeviceDTO;
import com.xhwl.common.enums.device.DeviceOnlineStatusEnum;
import com.xhwl.common.pojo.cent.alarm.AlarmManagement;
import com.xhwl.common.pojo.cent.device.Device;
import com.xhwl.common.query.cent.device.DeviceQuery;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author： lianghz
 * @Description：
 * @Date 2021/09/14/ 09:29
 */
@Service
public class DeviceIntegrationHaiKangHandler extends DeviceIntegrationHandler {
    private static final Logger log = LoggerFactory.getLogger(DeviceIntegrationHaiKangHandler.class);

    @Autowired
    private DeviceHaiKangHandler deviceHaiKangHandler;
    @Autowired
    private IDeviceCentService deviceCentService;

    @Autowired
    GeneralProducer generalProducer;

    @Override
    public void afterPropertiesSet() throws Exception {
        DeviceIntegrationFactory.register(2, this);
    }

    @Override
    public void pullDevice(DeviceIntegrationConfigDTO configDTO) {
        switch (configDTO.getDeviceType()) {
            case 1:
                this.pullDoor(configDTO);
                break;
        }
    }

    @Override
    public void pullDeviceOnlineStatus(DeviceIntegrationConfigDTO configDTO) {
        switch (configDTO.getDeviceType()) {
            case 1:
                this.pullDoorOnlineStatus(configDTO);
                break;
        }
    }

    private void pullDoor(DeviceIntegrationConfigDTO configDTO) {
        // 拉取数据
        List<DoorHaiKangDTO> doorHaiKangDTOList = deviceHaiKangHandler.pullDoor(configDTO);
        if (CollectionUtils.isEmpty(doorHaiKangDTOList)) {
            return;
        }
        // 转换数据
        List<DeviceDTO> deviceDTOList = this.handleDevice(configDTO, doorHaiKangDTOList);
        // 存储业务中台
        deviceCentService.asyncUpdateDevice(deviceDTOList);
    }

    public void pullDoorOnlineStatus(DeviceIntegrationConfigDTO configDTO) {
        // 拉取数据
        List<DoorHaiKangDTO> doorHaiKangDTOList = deviceHaiKangHandler.pullDoorOnlineStatus(configDTO);
        if (CollectionUtils.isEmpty(doorHaiKangDTOList)) {
            return;
        }
        // 转换数据
        List<Device> deviceList = this.handleDeviceOnlineStatus(configDTO, doorHaiKangDTOList);

        List<Device> offLineDevices = deviceList.stream().filter(s->s.getDeviceStatus().equals(DeviceOnlineStatusEnum.OFFLINE)).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(offLineDevices)) {
            DeviceQuery deviceQuery = new DeviceQuery();
            deviceQuery.setProjectId(configDTO.getProjectId());
            deviceQuery.setThirdDeviceIdList(offLineDevices.stream().map(Device::getThirdDeviceId).collect(Collectors.toList()));
            List<DeviceDTO> deviceDTOList = deviceCentService.listDevice(null, deviceQuery);
            offLineDevices.forEach(device->{
                AlarmManagement alarmManagement = new AlarmManagement();
                DeviceDTO deviceDTO = deviceDTOList.stream().filter(s-> StringUtils.equals( s.getThirdDeviceId(), device.getThirdDeviceId()))
                        .findAny().orElse(null);
                if(deviceDTO != null) {
                    //组装公共部分数据
                    alarmManagement.setProjectId(configDTO.getProjectId());
                    alarmManagement.setAlarmTime(new Date());
                    alarmManagement.setThirdDeviceId(device.getThirdDeviceId());
                    alarmManagement.setDeviceId(deviceDTO.getId());
                    //海康门禁离线告警
                    alarmManagement.setAlarmInventoryCode("17798944");
                    generalProducer.send(AlarmConstant.HAIKANG_ALARM_TOPIC, alarmManagement);
                }
            });
        }
        // 存储业务中台
        deviceCentService.asyncUpdateOnlineStatus(deviceList);
    }

    private List<DeviceDTO> handleDevice(DeviceIntegrationConfigDTO configDTO, List<DoorHaiKangDTO> doorHaiKangDTOList) {
        return doorHaiKangDTOList.stream().map(deviceHaiKangDTO -> {
            DeviceDTO deviceDTO = new DeviceDTO();
            deviceDTO.setProjectId(configDTO.getProjectId());
            deviceDTO.setProductId(configDTO.getProductId());
            deviceDTO.setCategoryId(configDTO.getCategoryEnum().getId());
            deviceDTO.setDeviceTypeId(configDTO.getDeviceType());
            deviceDTO.setName(deviceHaiKangDTO.getName());
            deviceDTO.setThirdDeviceId(deviceHaiKangDTO.getIndexCode());
            deviceDTO.setAttributeJson(new JSONObject());
            return deviceDTO;
        }).collect(Collectors.toList());
    }

    private List<Device> handleDeviceOnlineStatus(DeviceIntegrationConfigDTO configDTO, List<DoorHaiKangDTO> doorHaiKangDTOList) {
        return doorHaiKangDTOList.stream().map(deviceHaiKangDTO -> {
            Device device = new Device();
            device.setProjectId(configDTO.getProjectId());
            device.setThirdDeviceId(deviceHaiKangDTO.getDoorIndexCode());
            device.setDeviceTypeId(configDTO.getDeviceType());
            device.setOnlineStatus(deviceHaiKangDTO.getDoorState() == null || deviceHaiKangDTO.getDoorState() == 3 ? DeviceOnlineStatusEnum.OFFLINE : DeviceOnlineStatusEnum.ONLINE);
            return device;
        }).collect(Collectors.toList());
    }

}
